#ifndef GRETHIF_H
#define GRETHIF_H
#include <lwip/netif.h>
#include <netif/etharp.h>
#include <stdbool.h>

/* Set to 1 if using GRETH_GBIT, otherwise 0 */
#define GRETH_GBIT          1

/* Set to 10,100, or 1000 */
#define GRETH_SPEED         100

/* Set to 1 to run full duplex, 0 to run half duplex */
#define GRETH_FULLDUPLEX 1

/* GRETH APB Address */
#define GRETH_ADDR          0x80000B00

#define GRETH_FD            0x10
#define GRETH_RESET         0x40
#define GRETH_MII_BUSY      0x8
#define GRETH_MII_INVALID   0x10


#define GRETH_RXDESC_EN     0x800
#define GRETH_RXDESC_WR     0x1000
#define GRETH_RXDESC_IE     0x2000
#define GRETH_RXDESC_LEN    0x7FF

#define GRETH_TXDESC_LEN    0x07FF
#define GRETH_TXDESC_EN     0x0800
#define GRETH_TXDESC_WR     0x1000
#define GRETH_TXDESC_IE     0x2000
#define GRETH_TXDESC_UE     0x4000
#define GRETH_TXDESC_AL     0x8000


#define GRETH_INT_RX         0x4
#define GRETH_RXEN           0x2
#define GRETH_RXI            0x8
#define GRETH_RXBD_STATUS    0xFFFFC000
#define GRETH_RXBD_ERR_AE    0x4000
#define GRETH_RXBD_ERR_FT    0x8000
#define GRETH_RXBD_ERR_CRC   0x10000
#define GRETH_RXBD_ERR_OE    0x20000
#define GRETH_RXBD_ERR_LE    0x40000
#define GRETH_RXBD_IP_DEC    0x80000
#define GRETH_RXBD_IP_CSERR  0x100000
#define GRETH_RXBD_UDP_DEC   0x200000
#define GRETH_RXBD_UDP_CSERR 0x400000
#define GRETH_RXBD_TCP_DEC   0x800000
#define GRETH_RXBD_TCP_CSERR 0x1000000


/* GRETH configuration registers */
typedef struct _greth_regs {
    volatile int    control;        
    volatile int    status;        
    volatile int    esa_msb;        
    volatile int    esa_lsb;        
    volatile int    mdio;        
    volatile int    tx_desc_p;        
    volatile int    rx_desc_p;        
    volatile int    edclip;
} greth_regs;


struct descriptor 
{
    volatile unsigned int ctrl;
    volatile unsigned int addr;
};

struct greth_info {
    volatile greth_regs *regs;            /* Address of controller registers. */  
    struct eth_addr* ethaddr;
    struct descriptor* ptxd;
    struct descriptor* prxd;    
    unsigned int gbit;
    unsigned int phyaddr;
    unsigned int edcl;
    unsigned int txpnt;
    unsigned int rxpnt;  
    unsigned int txchkpnt;
    unsigned int rxchkpnt;

};


extern err_t 
grethif_init(struct netif* pnetif);

extern void
grethif_poll_in(struct netif* pnetif);

extern int 
grethif_get_linkstatus(struct netif* pnetif);

extern void
grethif_display_phy(struct netif* pnetif);
#endif

